module App::Items
    class Task < Qt::StandardItem
        attr_reader :tid, :stop_ms, :start_ms, :description, :duration,
          :project_name, :project_id, :started,
          :sametasks, :taken
        attr_reader :childitem_start, :childitem_stop, :childitem_duration

        alias_method :getChildItemWithStart, :childitem_start
        alias_method :getChildItemWithDuration, :childitem_duration
        alias_method :getChildItemWithStop, :childitem_stop

        def self.valid?(toggltask)
            # Tasks without project isn't handled, yet.
            return false unless toggltask["project"]
            return true
        end

        def self.create(model, description, parent)
            ret = model.toggl.newTask(description, parent)
            toggltask = ret
            new(toggltask)
        end

        def initialize(toggltask)
            super()

            begin
                @tid = toggltask["id"]
                @project_name = toggltask["project"]["name"]
                @project_id = toggltask["project"]["id"]
                @last_duration = 0
                @sametasks = []
                @taken = false
                update(toggltask)
            rescue
                p "Error in task:", toggltask
                raise
            end

            setEditable false
        end

        def to_s
            "tid='%s' start=%s stop=%s description='%s' duration=%d project_name='%s' project_id=%d started='%s'" %
            [
                @tid,
                Time.at(@start_ms/1000), Time.at(@stop_ms/1000), @description, @duration,
                @project_name, @project_id,
                @started
            ]
        end

        def start
            model.start_task self
        end

        def start!
            rep = model.toggl.startTask self
            update rep
        end

        def stop
            rep = model.toggl.stopTask self
            update rep
        end

        def toggle
            started ? stop : start
        end

        def destroy
            model.toggl.deleteTask self
            model._deleteTask self
        end

        def save
            model.toggl.setTask self, self.parent
        end

        def started?
            started
        end

        def update(toggltask)
            stop_s = (toggltask["stop"] or "0")
            @stop_ms = Time.parse(stop_s).to_i*1000
            @start_ms = Time.parse(toggltask["start"]).to_i*1000
            @description = toggltask["description"]
            @duration = toggltask["duration"]
            @started = false
            @started = true if @duration < 0
            @last_duration = @duration unless @started

            # Items for columns.
            @childitem_duration = MyStandardItem.new unless @childitem_duration
            @childitem_duration.setTextAlignment Qt::AlignRight
            @childitem_start = MyStandardItem.new unless @childitem_start
            @childitem_start.setTextAlignment Qt::AlignRight
            @childitem_stop = MyStandardItem.new unless @childitem_stop
            @childitem_stop.setTextAlignment Qt::AlignRight
            # Qt::StyledItemDelegate ..?

            showDescription
            # TODO eee, anti-MVC.
            setIcon KDE::Icon.new("dialog-ok") if @started
            setIcon KDE::Icon.new unless @started
            updateChildItem

            # Ha a setData() -val beallitott adat ugyanaz, akkor nem emittal!
            # A @started statusz valtozasa igy alapban nem emittalna, mi tesszuk.
            emitDataChanged
        end

        def description=(value)
            @description = value
            showDescription
        end

        def duration=(value)
            raise "You can't edit a running task" if @started
            @duration = value
            @last_duration = @duration
            updateChildItem
        end

        def stop_ms=(value)
            @stop_ms = value
            updateChildItem
        end
        def start_ms=(value)
            @start_ms = value
            updateChildItem
        end

        def start_time
            Time.at(@start_ms / 1000)
        end

        def stop_time
            Time.at(@stop_ms / 1000)
        end

        private
        def showDescription()
            setText @description.to_s
            setToolTip @description.to_s if @description.to_s.length > 16
        end


        public
        def addSameTask(task)
            if task.kind_of? Array
                task.delete self
                task.each { |t| t.eatenByTask self }
                @sametasks += task
            else
                return if task == self
                @sametasks << task
                task.eatenByTask self
            end
            updateChildItem

            # ahhoz kell, hogy sorban legyenek, hogy ha minket torolnek, tudjuk
            # hogy a .first a rangidos
            @sametasks.sort! { |a,b|
                return -1 if a.stop_ms == 0
                return 1 if b.stop_ms == 0
                b.stop_ms <=> a.stop_ms
            }
        end

        def deleteSameTask(task)
            raise "no such sametask" unless @sametasks.delete task
            updateChildItem
        end

        # Bekebelezi a Task -ot, illetve az eddigi ala tartozo Task -okat is
        def eatSameTask(task)
            addSameTask task
            addSameTask task.sametasks
            task.clearSameTask
            task.eatenByTask self
        end

        def eatenByTask(task)
            @taken = task
        end

        def clearSameTask()
            @sametasks = []
            updateChildItem
        end


        # Timer -bol hivogathato ha epp fut a taszk
        def updateChildItem
            dur = get_duration
            @sametasks.each { |task|
                #puts "#{self.description} is headtask with childs: #{task}"
                dur += task.get_duration
            }
            str = sprintf "%d:%02d", dur/60, dur%60
            @childitem_duration.setText str

            s = ""
            s = Time.at(@start_ms/1000).strftime("%a %H:%M")
            @childitem_start.setText s

            s = ""
            s += "(new)" if @stop_ms == 0
            s += Time.at(@stop_ms/1000).strftime("%a %H:%M") if @stop_ms > 0
            @childitem_stop.setText s
        end

        def get_duration()
            i = @duration
            i = Time.now.to_i + i if @started
            return i
        end


        def data(role)
            if role == Qt::UserRole
                # QtRuby-4.4.{0-1} requirement, otherwise segfaults
                return Qt::Variant.new(Time.now.to_i + 1) if @started
                return Qt::Variant.new(@stop_ms/1000)
            end
            super(role)
            #return qVariantFromValue(Qt::Color.new("darkorange")) if role == Qt::ForegroundRole
        end
    end
end
